<?php
// $Id: global.func.php 496 2012-07-31 10:02:45Z tomqin@gmail.com $

/**
 *  global.func.php 公共函数库
 *
 * @copyright       Copyright (C) 2010-2012 ARESCMS Inc.
 * @author          TomQin <tomqin@gmail.com>
 * @license         http://www.arescms.cn/license/
 */

if (!function_exists('array_replace_recursive'))
{
  function array_replace_recursive($array, $array1){
    function recurse($array, $array1){
      foreach ($array1 as $key => $value){
        // create new key in $array, if it is empty or not an array
        if (!isset($array[$key]) || (isset($array[$key]) && !is_array($array[$key]))){
          $array[$key] = array();
        }

        // overwrite the value in the base array
        if (is_array($value)){
          $value = recurse($array[$key], $value);
        }
        $array[$key] = $value;
      }
      return $array;
    }

    // handle the arguments, merge one by one
    $args = func_get_args();
    $array = $args[0];
    if (!is_array($array)){
      return $array;
    }
    for ($i = 1; $i < count($args); $i++){
      if (is_array($args[$i])){
        $array = recurse($array, $args[$i]);
      }
    }
    return $array;
  }
}

function array_drop_key(array $arr, array $keys){
    foreach($keys as $key)
        unset($arr[$key]);
    return $arr;
}

/**
 * 返回一个数组中的值
 *
 * @param array     数组
 * @param string    键值
 * @param mixed     默认值
 * @return mixed
 */
function array_get($array, $key, $default = null) {
    if(array_key_exists($key, $array)) {
        return $array[$key];
    }
    return $default;
}

/**
 * 返回一个数组中的字符串
 *
 * @param array     数组
 * @param string    键值
 * @param mixed     默认值
 * @return mixed
 */
function array_get_string($array, $key, $default = '') {
    return trim(isset($array[$key]) ? (string)$array[$key] : $default);
}

/**
 * 返回一个数组中的整型值
 *
 * @param array     数组
 * @param string    键值
 * @param integer   默认值
 * @return integer
 */
function array_get_int($array, $key, $default = 0) {
    return intval(isset($array[$key]) ? $array[$key] : $default);
}

/**
 * 返回一个数组中的浮点值
 *
 * @param array     数组
 * @param string    键值
 * @param integer   默认值
 * @return integer
 */
function array_get_double($array, $key, $default = 0) {
    return doubleval(isset($array[$key]) ? $array[$key] : $default);
}

/**
 * 返回一个数组中的长整型值
 *
 * @param array     数组
 * @param string    键值
 * @param integer   默认值
 * @return integer
 */
function array_get_long($array, $key, $default = 0){
    return sprintf('%u', array_get($array, $key, $default));
}

/**
 * 返回一个数组中的布尔判断值
 *
 * @param array     数组
 * @param string    键值
 * @param mixed     真值
 * @param mixed     假值
 * @return mixed
 */
function array_get_bool($array, $key, $true = 1, $false = 0){
    return (isset($array[$key])&&$array[$key]) ? $true : $false;
}

/**
 * 返回一个数组中在枚举范围内的值
 *
 * @param array     数组
 * @param string    键值
 * @param array     枚举数组
 * @param mixed     默认值
 * @return mixed
 */
function array_get_enum($array, $key, $enum, $default = ''){
    if(isset($array[$key])){
        return in_array($array[$key], $enum) ? $array[$key] : $default;
    }else{
        return $default;
    }
}

/**
 * 返回一个数组中在某一范围内的整数
 *
 * @param array     数组
 * @param string    键值
 * @param array     最小/大值的数组
 * @param integer   默认值
 * @return integer
 */
function array_get_range($array, $key, $range, $default = 0){
    if(isset($array[$key])){
        $var = intval($array[$key]);
        list($min, $max) = $range;
        if($min > $max){
            $tmp = $min;
            $min = $max;
            $max = $tmp;
        }
        return ($var >= $min && $var <= $max) ? $var : $default;
    }else{
        return $default;
    }
}
/**
 * 返回一个数组中的符合模式匹配的字符串
 *
 * @param array     数组
 * @param string    键值
 * @param string    规则匹配
 * @param string    默认值
 * @return string
 */
function array_get_match($array, $key, $rule, $default){
    if(isset($array[$key])){
        return preg_match($rule, $array[$key]) ? $array[$key] : $default;
    }else{
        return $default;
    }
}
/**
 * Get extension name of the specified file.
 *
 * @param  string   file name
 * @return string
 */
function fileext($filename) {
    //return strtolower(trim(substr(strrchr($filename, '.'), 1, 10)));
    return strtolower(pathinfo($filename, PATHINFO_EXTENSION));
}
/**
 * 返回经 htmlspecialchars 处理过的字符串
 *
 * @param string
 * @return string
 */
function h(&$string) {
    return isset($string) ? htmlspecialchars($string) : '';
}
/**
 * 返回经 intval 处理过的字符串
 *
 * @param string
 * @return string
 */
function i(&$string) {
    return isset($string) ? intval($string) : 0;
}
/**
 * 安全过滤函数
 *
 * @param $string
 * @return string
 */
function safe_replace($string) {
    $string = str_replace('%20','',$string);
    $string = str_replace('%27','',$string);
    $string = str_replace('%2527','',$string);
    $string = str_replace('*','',$string);
    $string = str_replace('"','&quot;',$string);
    $string = str_replace("'",'',$string);
    $string = str_replace('"','',$string);
    $string = str_replace(';','',$string);
    $string = str_replace('<','&lt;',$string);
    $string = str_replace('>','&gt;',$string);
    $string = str_replace("{",'',$string);
    $string = str_replace('}','',$string);
    return $string;
}
/**
 * 安全SQL查询字符串
 *
 * @param $string
 * @return string
 */
function safe_query($string) {
    $input = array(
        '%','_','\'','"','\\','?','*','<','>','=','|',
    );

    $string = str_replace($input,'',$string);
    return trim($string);
}
/**
 * 格式化文本域内容
 *
 * @param $string 文本域内容
 * @return string
 */
function trim_textarea($string) {
    $string = nl2br(str_replace(' ', '&nbsp;', $string));
    return $string;
}

/**
 * 转义 javascript 代码标记
 *
 * @param string
 * @return mixed
 */
function trim_script($str) {
    $str = preg_replace ( '/\<([\/]?)script([^\>]*?)\>/si', '&lt;\\1script\\2&gt;', $str );
    $str = preg_replace ( '/\<([\/]?)iframe([^\>]*?)\>/si', '&lt;\\1iframe\\2&gt;', $str );
    $str = preg_replace ( '/\<([\/]?)frame([^\>]*?)\>/si', '&lt;\\1frame\\2&gt;', $str );
    $str = preg_replace ( '/]]\>/si', ']] >', $str );
    return $str;
}
/**
 * 获取当前页面完整URL地址
 */
function get_url() {
    $sys_protocal = isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == '443' ? 'https://' : 'http://';
    $php_self = $_SERVER['PHP_SELF'] ? safe_replace($_SERVER['PHP_SELF']) : safe_replace($_SERVER['SCRIPT_NAME']);
    $path_info = isset($_SERVER['PATH_INFO']) ? safe_replace($_SERVER['PATH_INFO']) : '';
    $relate_url = isset($_SERVER['REQUEST_URI']) ? safe_replace($_SERVER['REQUEST_URI']) : $php_self.(isset($_SERVER['QUERY_STRING']) ? '?'.safe_replace($_SERVER['QUERY_STRING']) : $path_info);
    return $sys_protocal.(isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '').$relate_url;
}
/**
 * 字符截取 支持UTF8/GBK
 * @param $string
 * @param $length
 * @param $dot
 */
function cutstr($string, $length, $dot = ' ...') {
    $strlen = iconv_strlen($string, CHARSET);

    if($strlen > $length){
        return iconv_substr($string, 0, $length, CHARSET) . $dot;
    }else{
        return $string;
    }
}

/**
 * 程序执行时间
 *
 * @return integer  单位ms
 */
function execute_time() {
    $stime = explode (' ', SYS_START_TIM );
    $etime = explode (' ', microtime());
    return number_format(($etime[1] + $etime[0] - $stime[1] - $stime[0]), 6);
}

function get_cost_time() {
    $microtime = microtime(true);
    return $microtime - SYS_START_TIME;
}


/**
 * 产生随机字符串
 *
 * @param integer   输出长度
 * @param string    可选的 ，默认为 0123456789
 * @return string   字符串
 */
function random($length, $chars = '0123456789') {
    $hash = '';
    $max = strlen($chars) - 1;
    for($i = 0; $i < $length; $i++) {
        $hash .= $chars[mt_rand(0, $max)];
    }
    return $hash;
}

/**
 * 生成随机字符串
 *
 * @param integer   长度
 * @return string   字符串
 */
function randomstr($lenth = 6) {
    return random($lenth, '123456789abcdefghijklmnpqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ');
}

/**
 * 将数组转换为字符串
 *
 * @param array     数组
 * @param boolean   如果为0，则不使用new_stripslashes处理，可选参数，默认为1
 * @return string   返回字符串，如果 data 为空，则返回空
 */
function array2string($data, $isformdata = 1) {
    if($data == '') return '';
    return var_export($data, true);
}

/**
 * 转换字节数为其他单位
 *
 * @param integer   字节大小
 * @return string   返回大小
 */
function convert_size($filesize) {
    if ($filesize >= 1073741824) {
        $filesize = floor ($filesize / 1073741824 * 100) / 100 .' GB';
    } elseif ($filesize >= 1048576) {
        $filesize = floor ($filesize / 1048576 * 100) / 100 .' MB';
    } elseif($filesize >= 1024) {
        $filesize = floor ($filesize / 1024 * 100) / 100 . ' KB';
    } else {
        $filesize = $filesize.' Bytes';
    }
    return $filesize;
}

/**
 * 返回内存使用量
 *
 * @return string
 */
function memory_usage() {
    return convert_size(memory_get_usage());
}

/**
 * 字符串加密、解密函数
 *
 * @param string    字符串
 * @param string    ENCODE为加密，DECODE为解密，可选参数，默认为ENCODE，
 * @param string    密钥：数字、字母、下划线
 * @return string
 */
function auth_string($txt, $operation = 'ENCODE', $key = '') {
    $key  = $key ? $key : App::getConfig('system.auth_key');
    $txt  = $operation == 'ENCODE' ? (string)$txt : base64_decode($txt);
    $len  = strlen($key);
    $code = '';
    for($i=0; $i<strlen($txt); $i++){
        $k      = $i % $len;
        $code  .= $txt[$i] ^ $key[$k];
    }
    $code = $operation == 'DECODE' ? $code : base64_encode($code);
    return $code;
}


function crypt1($string, $isEncrypt = true) {
    $key = App::getConfig('system.auth_key');
    $dynKey = $isEncrypt ? hash('sha1', microtime(true)) : substr($string, 0, 40);
    $fixedKey = hash('sha1', $key);

    $dynKeyPart1 = substr($dynKey, 0, 20);
    $dynKeyPart2 = substr($dynKey, 20);
    $fixedKeyPart1 = substr($fixedKey, 0, 20);
    $fixedKeyPart2 = substr($fixedKey, 20);
    $key = hash('sha1', $dynKeyPart1 . $fixedKeyPart1 . $dynKeyPart2 . $fixedKeyPart2);

    $string = $isEncrypt ? $fixedKeyPart1 . $string . $dynKeyPart2 : (isset($string{339}) ? gzuncompress(base64_decode(substr($string, 40))) : base64_decode(substr($string, 40)));

    $n = 0;
    $result = '';
    $len = strlen($string);

    for ($n = 0; $n < $len; $n++) {
        $result .= chr(ord($string{$n}) ^ ord($key{$n % 40}));
    }
    return $isEncrypt ? $dynKey . str_replace('=', '', base64_encode($n > 299 ? gzcompress($result) : $result)) : substr($result, 20, -20);
}

/**
 * 分页
 *
 * @param int    总记录数
 * @param int    当前页码
 * @param int    每页记录数
 * @param string 分页链接规则 {PAGE} 字符用于替换真正的页码值
 * @param int    页码集合，默认10页一组
 * @return string
 */
function pages($total, $curr_page, $perpage = 20, $urlrule = '?page={PAGE}', $pagesets = 10) {
    $multipage = '';
    $page = $offset = $pages = 0;
    if($total > $perpage) {
        $page = $pagesets + 1;
        $offset = ceil($pagesets / 2 - 1);
        $pages  = ceil($total / $perpage);

        $from = $curr_page - $offset;
        $to   = $curr_page + $offset;
        $more = 0;
        if($page >= $pages) {
            $from = 2;
            $to   = $pages - 1;
        } else {
            if($from <= 1) {
                $to   = $page - 1;
                $from = 2;
            }  elseif($to >= $pages) {
                $from = $pages - ( $page - 2 );
                $to   = $pages - 1;
            }
            $more = 1;
        }
        $multipage .= '<a class="a1">'.$total.'条</a>';
        if($curr_page>0) {
            $multipage .= ' <a href="'.pageurl($urlrule, $curr_page-1).'" class="a1">上一页</a>';
            if($curr_page==1) {
                $multipage .= ' <span>1</span>';
            } elseif($curr_page>6 && $more) {
                $multipage .= ' <a href="'.pageurl($urlrule, 1).'">1</a> ... ';
            } else {
                $multipage .= ' <a href="'.pageurl($urlrule, 1).'">1</a>';
            }
        }
        for($i = $from; $i <= $to; $i++) {
            if($i != $curr_page) {
                $multipage .= ' <a href="'.pageurl($urlrule, $i).'">'.$i.'</a>';
            } else {
                $multipage .= ' <span>'.$i.'</span>';
            }
        }
        if($curr_page < $pages) {
            if($curr_page < $pages - 5 && $more) {
                $multipage .= ' ... <a href="'.pageurl($urlrule, $pages).'">'.$pages.'</a> <a href="'.pageurl($urlrule, $curr_page + 1).'" class="a1">下一页</a>';
            } else {
                $multipage .= ' <a href="'.pageurl($urlrule, $pages).'">'.$pages.'</a> <a href="'.pageurl($urlrule, $curr_page + 1).'" class="a1">下一页</a>';
            }
        } elseif($curr_page == $pages) {
            $multipage .= ' <span>'.$pages.'</span> <a href="'.pageurl($urlrule, $curr_page).'" class="a1">下一页</a>';
        } else {
            $multipage .= ' <a href="'.pageurl($urlrule, $pages).'">'.$pages.'</a> <a href="'.pageurl($urlrule, $curr_page + 1).'" class="a1">下一页</a>';
        }
    }
    return $multipage;
}

/**
 * 拼接分页链接
 *
 * @return integer
 */
function pageurl($urlrule, $page) {
    return str_replace('{PAGE}', $page, $urlrule);
}

/**
 * 计算真实页码
 *
 * @param int    页码
 * @param int    总记录数
 * @param int    每页记录数
 * @return string
 */
function real_page($page, $total, $perpage = 20){
    $perpage = intval($perpage);
    $total = intval($total);
    $page = intval($page);
    if($perpage <= 0) return 1;

    $pages = ceil($total / $perpage);
    if($page < 1) return 1;
    elseif($page > $pages) return $pages;
    else return $page;
}
////////////////////////////////////////////////////////////////////////

/**
 * 判断email格式是否正确
 * @param $email
 */
function is_email($email) {
    return strlen($email) > 6 && preg_match("/^([\w-.]+)@(([[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.)|(([\w-]+.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(]?)$/", $email);
}

/**
 * iconv 编辑转换
 */
if (!function_exists('iconv')) {
    function iconv($in_charset, $out_charset, $str) {
        $in_charset = strtoupper($in_charset);
        $out_charset = strtoupper($out_charset);
        if (function_exists('mb_convert_encoding')) {
            return mb_convert_encoding($str, $out_charset, $in_charset);
        } else {
            pc_base::load_sys_func('iconv');
            $in_charset = strtoupper($in_charset);
            $out_charset = strtoupper($out_charset);
            if ($in_charset == 'UTF-8' && ($out_charset == 'GBK' || $out_charset == 'GB2312')) {
                return utf8_to_gbk($str);
            }
            if (($in_charset == 'GBK' || $in_charset == 'GB2312') && $out_charset == 'UTF-8') {
                return gbk_to_utf8($str);
            }
            return $str;
        }
    }
}
/**
 * 对用户的密码进行加密
 * @param $password
 * @param $encrypt //传入加密串，在修改密码时做认证
 * @return array/password
 */
function password($password, $encrypt='') {
    $pwd = array();
    $pwd['encrypt'] =  $encrypt ? $encrypt : create_randomstr();
    $pwd['password'] = md5(md5(trim($password)).$pwd['encrypt']);
    return $encrypt ? $pwd['password'] : $pwd;
}


/**
 * 检查密码长度是否符合规定
 *
 * @param STRING $password
 * @return  TRUE or FALSE
 */
function is_password($password) {
    $strlen = strlen($password);
    if($strlen >= 6 && $strlen <= 20) return true;
    return false;
}

 /**
 * 检测输入中是否含有错误字符
 *
 * @param char $string 要检查的字符串名称
 * @return TRUE or FALSE
 */
function is_badword($string) {
    $badwords = array("\\",'&',' ',"'",'"','/','*',',','<','>',"\r","\t","\n","#");
    foreach($badwords as $value){
        if(strpos($string, $value) !== false) {
            return true;
        }
    }
    return false;
}

/**
 * 检查用户名是否符合规定
 *
 * @param STRING $username 要检查的用户名
 * @return  TRUE or FALSE
 */
function is_username($username) {
    $strlen = strlen($username);
    if(is_badword($username) || !preg_match("/^[a-zA-Z0-9_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]+$/", $username)){
        return false;
    } elseif ( 20 <= $strlen || $strlen < 2 ) {
        return false;
    }
    return true;
}

/**
 * 文本转换为图片
 * @param string $txt 图形化文本内容
 * @param int $fonttype 无外部字体时生成文字大小，取值范围1-5
 * @param int $fontsize 引入外部字体时，字体大小
 * @param string $font 字体名称 字体请放于phpcms\libs\data\font下
 * @param string $fontcolor 字体颜色 十六进制形式 如FFFFFF,FF0000
 */
function string2img($txt, $fonttype = 5, $fontsize = 16, $font = '', $fontcolor = 'FF0000',$transparent = '1') {
    if(empty($txt)) return false;
    if(function_exists("imagepng")) {
        $txt = urlencode(sys_auth($txt));
        $txt = '<img src="'.APP_PATH.'api.php?op=creatimg&txt='.$txt.'&fonttype='.$fonttype.'&fontsize='.$fontsize.'&font='.$font.'&fontcolor='.$fontcolor.'&transparent='.$transparent.'" align="absmiddle">';
    }
    return $txt;
}

/* */
function thumb_url(&$picture, $width, $height, $default = ''){
    if(empty($default)){
        $default = STATIC_URL.'img/thumb.gif';
    }
    if(!isset($picture) || empty($picture)){
        return $default;
    }

    $width  = intval($width);
    $height = intval($height);
    $thumb  = preg_replace('/(\.[a-z]{2,8})$/', "-{$width}x{$height}.jpg", $picture);
    if(is_file(UPLOAD_DIR.$thumb)){
        return UPLOAD_URL.$thumb;
    }else{
        if(is_file(UPLOAD_DIR.$picture)){
            $image = Image::createFromFile(UPLOAD_DIR.$picture);
            $image->thumb($width, $height)->saveAsJpeg(UPLOAD_DIR.$thumb);
            return UPLOAD_URL.$thumb;
        }else{
            return $default;
        }
    }
}

/* description 输出 */
function description($html, $length = 200){
    $html = trim(strip_tags($html));
    $html = preg_replace('/[\0\r\n\s]+/i', '', $html);
    return cutstr($html, $length);
}

/* 最小化 HTML 输出 */
function clean_html($html){
    //删除注释
    $html = preg_replace('/(\<\!\-\-.*\-\-\>)/iUs', '', $html);

    $lines = explode("\n", $html);
    $html = '';
    foreach($lines as $k => $v){
        $html .= trim($v)."\n";
    }
    return $html;
}

function jumpto($url, $forever = false){
    if($forever){
        header("HTTP/1.1 301 Moved Permanently");
    }
    header("Location: $url");
    exit;
}

function p($var){
    echo '<pre>';
    (!$var) ? var_dump($var) : print_r($var);
    echo '</pre>';
}
?>